package com.library.common.ext

import androidx.lifecycle.rxLifeScope
import com.library.common.base.BaseViewModel
import com.library.common.base.LoadingDialogEntity
import com.library.common.dto.MessageEvent
import com.library.common.net.NetConstant
import com.library.common.net.error.code
import com.library.common.net.loadingtype.LoadingType
import kotlinx.coroutines.CoroutineScope
import org.greenrobot.eventbus.EventBus

/**
 * 封装一下 RxHttp请求
 * @receiver BaseViewModel
 * @param requestDslClass [@kotlin.ExtensionFunctionType] Function1<HttpResultDsl, Unit>
 */
fun BaseViewModel.rxHttpRequest(requestDslClass: HttpRequestDsl.() -> Unit) {
    val httpRequestDsl = HttpRequestDsl()
    requestDslClass(httpRequestDsl)
    rxLifeScope.launch({
        // 携程体方法执行工作 请求完成 走到这里说明请求成功了
        httpRequestDsl.onRequest.invoke(this)
    }, {
        //如果有显示加载数据页面的，页面显示为错误状态页面
        if (httpRequestDsl.isLoadingType) statusView.set(LoadingType.SHOW_ERROR)
        //如果没有传递 onError参数 默认调用封装的逻辑
        if (httpRequestDsl.isShowDialogRequest && defUI.loading.value?.isShow == true) {
            defUI.loading.value = LoadingDialogEntity(
                httpRequestDsl.loadingMessage,
                false
            )
        }
        if (it.code == NetConstant.LOGIN_OUT) {
            EventBus.getDefault().post(MessageEvent(NetConstant.LOGIN_OUT))
        }
        if (httpRequestDsl.onError != null) {
            //请求失败时将错误日志打印一下 防止错哪里了都不晓得
            it.printStackTrace()
            "请求出错了----> ${it.message}".logE()
            //传递了 onError 需要自己处理
            httpRequestDsl.onError?.invoke(it)
        }
    }, {
        //发起请求时
        if (httpRequestDsl.isShowDialogRequest) {
            defUI.loading.value = LoadingDialogEntity(
                httpRequestDsl.loadingMessage,
                true
            )
        }
        if (httpRequestDsl.isLoadingType && httpRequestDsl.isRefresh) statusView.set(LoadingType.SHOW_LOADING)
    }, {
        //请求结束时
        if (httpRequestDsl.isShowDialogRequest && defUI.loading.value?.isShow == true) {
            defUI.loading.value = LoadingDialogEntity(httpRequestDsl.loadingMessage, false)
        }
    })
}

class HttpRequestDsl {
    var onRequest: suspend CoroutineScope.() -> Unit = {} //请求工作 在这里执行网络接口请求，然后回调成功数据
    var onError: ((Throwable) -> Unit)? = null //错误回调，默认为null 如果你传递了他 那么就代表你请求失败的逻辑你自己处理
    var isShowDialogRequest: Boolean = false //是否显示网络请求框 默认false 不显示
    var loadingMessage: String = "加载中..."//网络请求框提示文字
    var isLoadingType = false// 请求时是否需要loading类型
    var isRefresh = false// 请求时，是否是刷新页面
}
